﻿#region Copyright

// All Material Copyright © 2010 Dynamic Concepts Development Corp., All Rights Reserved.
//      Portions Copyright © 1984-2009 Dynamic Concepts Development Corp., All Rights Reserved.
// For further information please contact: SoftwareSupport@dynconcepts.com
// Dynamic Concepts Development Corp.  311 W 57th St. Suite #422, New York, NY 10019

#endregion

#region Using References

using System;
using System.Collections.Generic;

#endregion

namespace DynConDevCorp.OpenArch.SupportLibrary.ApplicationInfrastructure
{
    public class QueuedLogger
    {
        #region Constructors

        private QueuedLogger()
        {
        }

        #endregion

        #region Public Properies and Indexers

        public static QueuedLogger GlobalInstance
        {
            get { return sr_GlobalInstance; }
        }

        #endregion

        #region Public Methods

        public void Fire_LoggedMessageReady(LoggedMessage message)
        {
            EventHandler<LoggedMessageEventArgs> shadow = m_LoggedMessageReadyHandlers;
            if (shadow != null)
            {
                shadow(this, new LoggedMessageEventArgs(message));
            }
        }

        public void Log(MessageSeverity severity, string text)
        {
            LoggedMessage message = new LoggedMessage(severity, text);
            r_MessageQueue.Enqueue(message);
            Fire_LoggedMessageReady(message);
        }

        public void Log(MessageSeverity severity, object item)
        {
            string message = string.Format("{0}", item);
            Log(severity, message);
        }

        public void Log(MessageSeverity severity, string format, params object[] elements)
        {
            string message = string.Format(format, elements);
            Log(severity, message);
        }

        #endregion

        #region Public Events

        public event EventHandler<LoggedMessageEventArgs> LoggedMessageReady
        {
            add
            {
                m_LoggedMessageReadyHandlers += value;
                DequeueLoggedMessages(value);
            }
            remove { m_LoggedMessageReadyHandlers -= value; }
        }

        #endregion

        #region Public Enums

        #region MessageSeverity enum

        public enum MessageSeverity
        {
            Critical,
            Error,
            Warning,
            Information,
            Debug
        }

        #endregion

        #endregion

        #region Private Methods

        private void DequeueLoggedMessages(EventHandler<LoggedMessageEventArgs> handler)
        {
            while (r_MessageQueue.Count > 0)
            {
                LoggedMessage message = r_MessageQueue.Dequeue();
                handler(this, new LoggedMessageEventArgs(message));
            }
        }

        #endregion

        #region Static Fields and Constants

        private static readonly QueuedLogger sr_GlobalInstance = new QueuedLogger();

        #endregion

        #region Instance Fields (ReadOnly)

        private readonly Queue<LoggedMessage> r_MessageQueue = new Queue<LoggedMessage>();

        #endregion

        #region Instance Fields (Mutable)

        private EventHandler<LoggedMessageEventArgs> m_LoggedMessageReadyHandlers;

        #endregion

        #region Nested type: LoggedMessage

        public class LoggedMessage
        {
            #region Constructors

            public LoggedMessage(MessageSeverity severity, string text)
            {
                r_Severity = severity;
                r_Text = text;
                r_TimeStamp = DateTime.UtcNow;
            }

            #endregion

            #region Public Properies and Indexers

            public MessageSeverity Severity
            {
                get { return r_Severity; }
            }

            public string Text
            {
                get { return r_Text; }
            }

            public DateTime TimeStamp
            {
                get { return r_TimeStamp; }
            }

            #endregion

            #region Instance Fields (ReadOnly)

            private readonly MessageSeverity r_Severity;
            private readonly string r_Text;
            private readonly DateTime r_TimeStamp;

            #endregion
        }

        #endregion

        #region Nested type: LoggedMessageEventArgs

        public class LoggedMessageEventArgs : EventArgs
        {
            #region Constructors

            public LoggedMessageEventArgs(LoggedMessage message)
            {
                r_Message = message;
            }

            #endregion

            #region Public Properies and Indexers

            public LoggedMessage Message
            {
                get { return r_Message; }
            }

            #endregion

            #region Instance Fields (ReadOnly)

            private readonly LoggedMessage r_Message;

            #endregion
        }

        #endregion
    }
}